
package com.scott.itcast.condition;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 用Lock实现互斥。用Condition实现通信
 * 子线程循环10次，接着主线程循环100次
 * 接着又回到子线程循环10次，接着再回到主线程循环100次
 * 如此循环50次。请写出程序
 */
public class ConditionTest {

	public static void main(String[] args) {
		
		
		final Business business = new Business();
		
		//第1个线程
		new Thread(new Runnable(){
			public void run() {
				for(int i=1;i<=50;i++){
					business.sub(i);
				}
			}
			
		}).start();
		
		//第2个线程
		for(int i=1;i<=50;i++){
			business.main(i);
		}
		
		

	}
	
	//加了static的类就相当于外部类
	static class Business{
		
		//重入锁 ReentrantLock 是一种递归无阻塞的同步机制。 实现互斥
		private Lock lock  = new ReentrantLock();
		
		//实现 通信
		private Condition condition = lock.newCondition();
		
		
		private boolean flag = true;
		
		
		public /*synchronized*/ void sub(int i){
			
			lock.lock();
			try{
				//使用while可以消除 伪唤醒  spurious wakeup
				while(!flag){
					try {
						//this.wait();
						condition.await(); //等待
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
				
				for(int j=1; j<=10; j++){
					System.out.println("子线程["+Thread.currentThread().getName()+ "]。外层循环次数：[" + i + "]。内存循环次数：["+j+"]");
				}
				System.out.println();
				flag=false;
				
				//唤醒main线程
				//this.notify();
				condition.signal();
				
			}finally{
				lock.unlock();
			}
			
			
			
			
		}

		public /*synchronized*/ void main(int i){
			lock.lock();
			try{
				//使用while可以消除 伪唤醒  spurious wakeup
				while(flag){
					try {
						//this.wait();
						condition.await();
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
				
				for(int j=1; j<=100; j++){
					System.out.println("主线程["+Thread.currentThread().getName()+ "]。外层循环次数：[" + i + "]。内存循环次数：["+j+"]");
				}
				System.out.println();
				flag=true;
				
				//唤醒sub线程
				//this.notify();
				condition.signal(); //向…发信号  signal
			}finally{
				lock.unlock();
			}
		}
	}
}


